1. Technical Field
The present invention is generally directed to a method and apparatus for providing a modular J2EE architecture. More specifically, the present invention is directed to a method and apparatus for providing a plug-in based extendable J2EE architecture.
2. Description of Related Art
Large software projects often utilize componentized development so that the project is broken into smaller pieces that can be completed by individual development teams. This reduces the complexity of the development process by isolating each development team from the affects of changes in other parts of the project. One architecture that has been developed to aid in this componentized development process is the Java 2 Platform Enterprise Edition (J2EE), available from Sun Microsystems. J2EE is a platform for building distributed enterprise applications that operate in a middle tier between the user's machine and the enterprise databases and legacy information systems. The J2EE architecture is composed of Enterprise JavaBeans (EJBs), JavaServer Pages (JSPs), Java servlets, and a variety of interfaces for linking to the information resources in the enterprise. The J2EE interfaces include Java DataBase Connectivity (JDBC) for database, Java Naming and Directory Interface (JNDI) for directories, Java Transaction API (JTA) for transactions, Java Messaging Service (JMS) for messaging, and JavaMail for e-mail systems.
The J2EE applications are typically componentized into a presentation tier, a business tier, and a data tier. The presentation tier deals with the components that represent the manner by which information is presented to a user. The business tier includes the business logic regarding how the J2EE application is to operate on requests from users via the presentation tier and on the data in the data tier. The data tier is the raw enterprise data or information, and the mechanisms for accessing this data/information, that is used as a basis for performing the operations defined by the business tier.
While J2EE was designed to promote the componentized development of applications, the J2EE model in may respects hinders the division of these tiers into multiple development components. For example, the presentation tier and the business tier are combined into a single archive file (WAR file) and are not maintained separately. While these tiers could be packaged into multiple WAR files, each WAR file would have its own configuration data and would not be able to share resources, such as a context-root or a session, with the other WAR files. Thus, there are negative consequences to forcing this separation or componentization in the J2EE model.
Another componentized architecture is the Eclipse architecture available from Bolour Computing. Eclipse is an extensible platform for building Integrated Development Environments (IDEs). Eclipse provides a core of services for controlling a set of tools working together to support programming tasks. Tool builders contribute to the Eclipse platform by wrapping their tools in pluggable components, called Eclipse plug-ins, which conform to Eclipse's plug-in contract. The basic mechanism of extensibility in Eclipse is that new plug-ins can add new processing elements to existing plug-ins and Eclipse provides a set of core plug-ins to bootstrap this process.
Even though the Eclipse platform is specialized for building IDEs, the core of its concepts and facilities supports a general model for composing an application from constituent parts developed by multiple vendors. A plug-in in Eclipse is a component that provides a certain type of service within the context of the Eclipse workbench. By a “component” what is meant is an object that may be configured into a system at system deployment time. The Eclipse runtime provides an infrastructure to support the activation and operation of a set of plug-ins working together to provide a seamless environment for development activities.
Within a running Eclipse instance, a plug-in is embodied in an instance of a plug-in runtime class, or plug-in class for short. The plug-in class provides configuration and management support for the plug-in instance. A plug-in class in Eclipse must extend org.eclipse.core.runtime.Plugin, which is an abstract class that provides generic facilities for managing plug-ins.
An Eclipse installation includes a plugins folder where individual plug-ins are deployed. Each plug-in is installed in its own folder under the plugins folder. A plug-in is described in an XML manifest file, called plugin.xml, residing in the plug-in's folder. The manifest file tells the Eclipse runtime what it needs to know to activate the plug-in.
The parsed contents of plug-in manifest files are made available programmatically through a plug-in registry API and parsed plug-in specifications are cached in an in-memory repository called the plug-in registry. The Eclipse runtime instantiates an instance of each plug-in by using the plug-in registry API. The plug-in registry API is also used by provider-supplied plug-in code to obtain information about plug-ins.
The Eclipse Platform Plug-in Manifest Specification documents the XML elements and attributes used in defining plug-ins. In the plug-in manifest file, each plug-in has a unique identifier (XML attribute id) that is used to refer to a plug-in within the manifest files of other, related, plug-ins. The unique identifier may also be used within provider-supplied plug-in code to access the plug-in's running instance.
Plug-in instances are managed by the Eclipse runtime, and are accessed by using the Eclipse platform. Plug-in instances are not constructed by application programs.
Deploying a plug-in in an Eclipse installation involves copying the resources that constitute the plug-in (the manifest file, jar files, and other resources) into an individual folder for the plug-in, under the installation's plugins directory. Such a plug-in can then be activated by the Eclipse runtime when it is required to perform some function. Activating a plug-in means loading its runtime class and instantiating and initializing its instance.
The main function of a plug-in class is to do special processing during plug-in activation and deactivation, e.g., to allocate and release resources. For simple plug-ins, no specific activation or deactivation processing is required and therefore, no specific plug-in class needs to be provided by the plug-in designer. In that case, the Eclipse runtime automatically provides a default plug-in class for the plug-in instance. When the plug-in needs to do something specific to activate or deactivate itself, the plug-in designer provides overrides for the activation and deactivation methods of the class, respectively called startup and shutdown, and includes the fully-qualified name of this specific plug-in subclass as the value of the attribute class in the corresponding plug-in manifest file.
Eclipse includes a plug-in management kernel, known as the Eclipse platform, or the Eclipse runtime, and certain core plug-ins that are present in every Eclipse deployment. The identities of these core plug-ins are hard-coded into the Eclipse platform, and the platform knows to activate these plug-ins in each running instance of Eclipse. Non-core plug-ins, on the other hand, are activated when required by other plug-ins.
In the Eclipse model, a plug-in may be related to another plug-in by one of two relationships: dependency and an extension. With a dependency relationship, the roles in this relationship are dependent plug-in and prerequisite plug-in. A prerequisite plug-in supports the functions of a dependent plug-in. In an extension relationship, the roles in this relationship are host plug-in and extender plug-in. An extender plug-in extends the functions of a host plug-in. These relationships are specified declaratively in plug-in manifest files through the XML elements required and extension.
A non-core plug-in that has been deployed in an Eclipse installation may be activated in a running instance of Eclipse if it is transitively related to a core Eclipse plug-in by the union of the dependency and the extension relations. Such a plug-in will be activated when its functions are required to support or to extend the functions of another plug-in. A plug-in that is deployed but unreachable from any core plug-in via the dependency and extension relations might as well not be deployed from the point of view of plug-in activation. Even a reachable plug-in may remain unactivated in a running instance for some time (or for the lifetime of the instance) if no user action or other triggering event elicits its use.
An extension is defined by an extender plug-in and causes a host plug-in to modify its behavior. Typically, this modification of behavior includes the addition of processing elements to the host plug-in, and the customization of the behavior of these additional elements by services provided by the extender plug-in.
In simple cases, a single act of extension adds a single callback object to the environment, through which the host and extender plug-ins communicate, however, it could add more than one callback object to the environment. The callback object is different from the host and extender plug-in objects and, unlike these objects, which are components that are automatically instantiated and managed by the Eclipse platform, a callback object is a “plain old Java object” that is instantiated and managed specifically by provider-supplied code.
While Eclipse provides an extendible architecture in which components may be provided as plugins to a core set of services for creating IDEs, the plug-in based architecture has not, and cannot, be applied to the development of J2EE applications using known mechanisms. This is primarily because J2EE applications must be integrated into a single WAR file for deployment so that each component may have a single set of configuration data and be able to share resources. With the Eclipse architecture, the components are maintained as separate files.
Thus, it would be beneficial to have a method and apparatus that permits the extensibility of a plug-in based architecture, such as the Eclipse architecture, to be used with the development of J2EE applications. Moreover, it would be beneficial to have a method and apparatus for generating a single logical J2EE application from several individual components that act as a single, integrated application at runtime.